﻿using System;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using wt.wine.Application.Common.Interfaces;
using Microsoft.AspNetCore.Mvc;
using System.Threading;
using System.Linq;
using System.Collections.Generic;
using wt.wine.Domain.Entities;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.EntityFrameworkCore;

namespace WebAPI.Filters
{
    /// <summary>
    /// 登录校验
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class PermissioneFilter : AuthorizeAttribute, IAuthorizationRequirement, IAuthorizationFilter
    {
        public string ActionName { get; set; }
        public PermissioneFilter(string ActionName)
        {
            this.ActionName = ActionName;
        }

        public async void OnAuthorization(AuthorizationFilterContext context)
        {
            if (!string.IsNullOrWhiteSpace(ActionName))
            {
                //判断页面是否又权限

                var svc = context.HttpContext.RequestServices;
                var currentuserservices = svc.GetRequiredService<ICurrentUserService>();
                int userid = currentuserservices.GetUserId();
                int roleid = currentuserservices.GetRoleId();
                if (userid <= 0 || roleid == 0)
                {
                    context.Result = new ObjectResult("Invalidate value") { StatusCode = 401 };
                    return;
                }
                var menuResponse = svc.GetRequiredService<IMenuTableRepository>();
                List<menutable> list = new List<menutable>() { };
                var memorycache = svc.GetRequiredService<IMemoryCache>();
                string key = "rolePermissionid"+roleid;
                list = memorycache.Get<List<menutable>>(key);
                if (list == null)
                {
                    var dbcontent = svc.GetRequiredService<IApplicationDbContext>();

                    list = dbcontent.menutable.AsNoTracking().Where(p => p.ifshow == 1).ToList();
                    list = list == null ? new List<menutable>() { } : list;
                    list.ForEach(p => { p.ifshow = 0; });
                    var list_role = dbcontent.rolemenutable.AsNoTracking().Where(p => p.roleid == roleid && p.state >= 0).ToList();
                    if (list.Any() && list_role != null && list_role.Any())
                    {
                        for (int i = 0; i < list.Count(); i++)
                        {
                            if (list_role.Where(p => p.meunid == list[i].id).Count() > 0)
                            {
                                list[i].ifshow = 1;
                            }
                        }
                       
                    }
                    memorycache.Set<List<menutable>>(key, list, TimeSpan.FromDays(2));
                }

                if (!(list != null && list.Any()))
                {
                    context.Result = new ObjectResult("Invalidate value") { StatusCode = 401 };
                    return;
                }
                bool isHasPermission = false;
                List<string> list_permission = ActionName.Split(',').ToList();
                for (int i = 0; i < list_permission.Count(); i++)
                {
                    if (list.Where(p => p.actionname == list_permission[i] && p.ifshow == 1).Count() > 0)
                    {
                        isHasPermission = true;
                        break;
                    }
                }
                if (!isHasPermission)
                {
                    context.Result = new ObjectResult("Invalidate value") { StatusCode = 401 };
                    return;
                }

            }


        }
    }
}
